/**
 * @file
 * <pre> CPE 357 Spring 2011
 * -------------------
 *
 *  Program "describe the program here (without quotes)"
 *
 *  Last Modified: Wed Oct 29 13:39:06 PM PDT 2008</pre>
 *  @author Matthew Tondreau
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "window.h"
#include "utility.h"
#include "client.h"
#include "debug.h"
#include <setjmp.h>
#include <pthread.h>
/** Main entry.
 * @param argc the number of tokens on the input line.
 * @param argv an array of tokens.
 * @return 0 on success, 1-255 on failure
 */
int
main(int argc, char *argv[])
{ 
  ChatWindows cw;
  int sk = 0;
  Message m;
  //const char *str;
  const char* port = "5577";
  STATES state = SETUP;
  pthread_t thread;
  thread_param tp;
  if( argc != 2 && argc != 3 ) {
     fprintf(stderr,"usage: %s <server ip> <port>\n", argv[0]);
     exit(EXIT_FAILURE);
  }
  if( argc == 3 ) {
     port = argv[2];
  }

  while( true ) {
     if( setjmp( env ) == 1 ) {
         state = EXIT;
     }
     switch( state ) {
        /** sets up the windows and signal handling */
     case SETUP:
        DMSG("SETUP")
        state = setup( cw, sk, argv[1], port);
        break;
     case LOGIN:
        DMSG("LOGIN");
        state = login( cw, sk );
        tp.cw =&cw;
        tp.sk = sk;
        pthread_create( &thread, NULL, get_input, &tp);
        break;
     case SELECT:
        DMSG("SELECT");
        state = wait_on_select(sk, m);
        break;
     case UPDATE:
        DMSG("UPDATE");
        state = new_message(m, cw);
        break;
     case REFUSED:
        DMSG("REFUSED");
        /** print message then exit */
        state = refused();
        break;
     case ERROR:
        DMSG("ERROR");
        perror(argv[0]);
         CloseWindows(cw);      
        if( sk ) {
            SYSCALL( close( sk ) == -1, argv[0]);
        }
        exit(EXIT_FAILURE);
        break;
     case EXIT:
        DMSG("EXIT");
         CloseWindows(cw);      
        if( sk ) {
            SYSCALL( close( sk ) == -1, argv[0]);
        }
        exit(EXIT_SUCCESS);
     }
  }

  /*
  */
   return EXIT_SUCCESS;
}

